/*
 * Copyright (C) 2025 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

use crate::common::constants::*;
use crate::common::types::Udid;
use crate::log_e;
use crate::traits::crypto_engine::{CryptoEngineRegistry, KeyPair};
use crate::traits::misc_manager::{MiscManager, TokenKey};
use crate::Vec;
use core::mem::size_of;

const DEFAULT_TOKEN_KEY: TokenKey = TokenKey {
    mac_key: *b"huks_default_user_auth_token_mac",
    cipher_key: *b"huks_default_user_auth_cipherkey",
};

const ATL_TABLE: [(AuthTrustLevel, AuthCapabilityLevel, ExecutorSecurityLevel); 6] = [
    (AuthTrustLevel::Atl4, AuthCapabilityLevel::Acl3, ExecutorSecurityLevel::Esl2),
    (AuthTrustLevel::Atl3, AuthCapabilityLevel::Acl3, ExecutorSecurityLevel::Esl1),
    (AuthTrustLevel::Atl3, AuthCapabilityLevel::Acl2, ExecutorSecurityLevel::Esl2),
    (AuthTrustLevel::Atl2, AuthCapabilityLevel::Acl2, ExecutorSecurityLevel::Esl1),
    (AuthTrustLevel::Atl1, AuthCapabilityLevel::Acl1, ExecutorSecurityLevel::Esl1),
    (AuthTrustLevel::Atl0, AuthCapabilityLevel::Acl0, ExecutorSecurityLevel::Esl0),
];

pub struct DefaultMiscManager {
    udid: Option<Udid>,
    key_pair: Option<KeyPair>,
}

impl DefaultMiscManager {
    pub fn new() -> Self {
        DefaultMiscManager {
            udid: None,
            key_pair: None,
        }
    }
}

impl MiscManager for DefaultMiscManager {
    fn get_token_key(&self) -> Result<TokenKey, ErrorCode> {
        Ok(DEFAULT_TOKEN_KEY)
    }

    fn get_distribute_key(&self, peer_udid: Udid) -> Result<crate::Vec<u8>, ErrorCode> {
        const DUMMY_DISTRIBUTE_DEVICE_KEY: &[u8; 32] = b"USER_AUTH_DISTRIBUTED_DEVICE_KEY";

        let mut salt = Vec::with_capacity(size_of::<Udid>() * 2);
        let local_udid = self.get_udid()?;
        if local_udid > peer_udid {
            salt.extend_from_slice(&local_udid.0);
            salt.extend_from_slice(&peer_udid.0);
        } else {
            salt.extend_from_slice(&peer_udid.0);
            salt.extend_from_slice(&local_udid.0);
        }

        let mut origin_key_data =
            Vec::with_capacity(DUMMY_DISTRIBUTE_DEVICE_KEY.len() + salt.len());
        origin_key_data.extend_from_slice(DUMMY_DISTRIBUTE_DEVICE_KEY);
        origin_key_data.extend_from_slice(&salt);

        // 计算SHA256哈希
        CryptoEngineRegistry::get().sha256(&origin_key_data)
    }

    fn set_udid(&mut self, udid: Udid) -> Result<(), ErrorCode> {
        self.udid = Some(udid);
        Ok(())
    }

    fn get_udid(&self) -> Result<Udid, ErrorCode> {
        if self.udid.is_none() {
            log_e!("udid not set");
            return Err(ErrorCode::GeneralError);
        }

        Ok(self.udid.unwrap())
    }

    fn set_local_key_pair(&mut self, key_pair: KeyPair) -> Result<(), ErrorCode> {
        self.key_pair = Some(key_pair);
        Ok(())
    }

    fn get_local_key_pair(&self) -> Result<KeyPair, ErrorCode> {
        match &self.key_pair {
            Some(k) => Ok(k.clone()),
            None => {
                log_e!("key pair not set");
                Err(ErrorCode::GeneralError)
            }
        }
    }

    fn get_auth_trust_level(&self, acl: AuthCapabilityLevel, esl: ExecutorSecurityLevel) -> AuthTrustLevel {
        for (atl_table, acl_table, esl_table) in ATL_TABLE {
            if acl >= acl_table && esl >= esl_table {
                return atl_table;
            }
        }
        return AuthTrustLevel::Atl0;
    }

}
